package commons.hibernate;

import groovy.lang.Closure;
import groovy.util.Eval;

import java.util.Set;

import org.codehaus.groovy.grails.commons.GrailsApplication;
import org.codehaus.groovy.grails.commons.GrailsDomainClass;
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsDomainBinder;
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsHibernateUtil;
import org.codehaus.groovy.grails.orm.hibernate.cfg.Mapping;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.hibernate.cfg.Mappings;

import commons.meta.RuntimeApplication;

public class BizConfiguration extends Configuration {

	private static final long serialVersionUID = -6973271165446780683L;

	private boolean configLocked;
	
	private RuntimeApplication application; 

	@Override
	protected void secondPassCompile() throws MappingException {
		if (configLocked) {
			return;
		}

		// set the class loader to load Groovy classes
		if (application != null) {
			Thread.currentThread().setContextClassLoader(application.getClassLoader());
		}

//		configureDomainBinder(grailsApplication, domainClasses);
//
//		for (GrailsDomainClass domainClass : domainClasses) {
//			if (!GrailsHibernateUtil.usesDatasource(domainClass, dataSourceName)) {
//				continue;
//			}
//			final Mappings mappings = super.createMappings();
//			Mapping m = GrailsDomainBinder.getMapping(domainClass);
//			mappings.setAutoImport(m == null || m.getAutoImport());
//			GrailsDomainBinder.bindClass(domainClass, mappings, sessionFactoryBeanName);
//		}

		super.secondPassCompile();
		configLocked = true;
	}
	
    public static void configureDomainBinder(GrailsApplication grailsApplication, Set<GrailsDomainClass> domainClasses) {
        Object defaultMapping = Eval.x(grailsApplication, "x.config?.grails?.gorm?.default?.mapping");
        // do Grails class configuration
        for (GrailsDomainClass domainClass : domainClasses) {
            if (defaultMapping instanceof Closure) {
                GrailsDomainBinder.evaluateMapping(domainClass, (Closure<?>)defaultMapping);
            }
            else {
                GrailsDomainBinder.evaluateMapping(domainClass);
            }
        }
    }

	public RuntimeApplication getApplication() {
		return application;
	}

	public void setApplication(RuntimeApplication application) {
		this.application = application;
	}
}
